﻿using System;
using System.Reflection;
using MugenInjection.Delegates;
using MugenInjection.Infrastructure;

namespace MugenInjection.Parameters
{
    /// <summary>
    ///     Represents the value of a field parameter.
    /// </summary>
    public class FieldParameter : InjectionParameter
    {
        #region Constructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="FieldParameter" /> class.
        /// </summary>
        public FieldParameter(string name, ParameterDelegate<object> getValueDelegate, Type type = null)
            : base(MemberTypes.Field, name, getValueDelegate)
        {
            // ReSharper disable DoNotCallOverridableMethodsInConstructor
            ParameterType = type;
            // ReSharper restore DoNotCallOverridableMethodsInConstructor
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="FieldParameter" /> class.
        /// </summary>
        public FieldParameter(string name, object value)
            : base(MemberTypes.Field, name, value)
        {
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="FieldParameter" /> class.
        /// </summary>
        public FieldParameter(string name, Type parameterType, object value)
            : base(MemberTypes.Field, name, value)
        {
            Validate.ArgumentNotNull(parameterType, "parameterType");
            // ReSharper disable DoNotCallOverridableMethodsInConstructor
            ParameterType = parameterType;
            // ReSharper restore DoNotCallOverridableMethodsInConstructor
        }

        #endregion

        #region Overrides of InjectionParameter

        /// <summary>
        ///     Determines whether the specified request can be resolved, this method will be invoked if <c>CanResolveDelegate</c> is null.
        /// </summary>
        /// <param name="memberInfo">
        ///     The specified <see cref="MemberInfo" />
        /// </param>
        /// <param name="parameter">
        ///     The specified <see cref="ParameterInfo" />
        /// </param>
        /// <returns>
        ///     <c>True</c> if the specified request has been resolved; otherwise, <c>false</c>.
        /// </returns>
        protected override bool CanResolveInternal(MemberInfo memberInfo, ParameterInfo parameter)
        {
            var fieldInfo = (FieldInfo)memberInfo;
            return Name.Equals(memberInfo.Name) && IsAssignableParameter(fieldInfo.FieldType);
        }

        #endregion
    }
}